#ifndef PROPERTYMAPPER_H
#define PROPERTYMAPPER_H

#include <QObject>
#include <QVariant>
#include "sh_global.h"

/**
 * @brief The PropertyMapper class
 * Maps onject property changed to single method with property name and it's value
 * Example usage:
 * PropertyMapper mapper(object, "propertyChanged", this);
 * //! propertyChanged(const QString &propertyName, const QVariant &value);
 * mapper.addProperty("simple", "property1", object1, false);
 * mapper.addProperty("quick", "property2", qmlView.rootObject(), true);
 * // now when property1 changes, object->propertyChanged("simple", <new value>) called,
 * // value is recieved from property chagnedSignal
 * // and when property2 changes, object->propertyChanged("quick", <new value>) called,
 * // but value is obtained from object itself ( object2->property("property2") )
 *
 * You can set property by calling setMappedProperty("quick", "value")
 * Or get it with mappedProperty("quick")
 */
class SHSHARED_EXPORT PropertyMapper : public QObject
{
public:
    PropertyMapper(QObject *mapToObject, const char *mapToMethod, QObject *parent = 0);
    int addProperty(const QString &propertyName, const char *mappingPropertyName,
                     QObject *mappingObject, bool isQuickProperty);
    void setMappedProperty(const QString &name, const QVariant &value);
    QVariant mappedProperty(const QString &name) const;

    int qt_metacall(QMetaObject::Call call, int id, void **arguments);

    // called when property is binded, mapToMethod will not be called that way!
    bool setProperty(const char *name, const QVariant &value);

protected:
    bool eventFilter(QObject *object, QEvent *event);
private:
    QObject *m_mapTo;
    const char *m_toMethod;
    QHash<QString, int> m_propertyIndices;
    typedef struct {
        QString name;
        QVariant::Type type;
        const char *mappingName;
        QObject *mappingObject;
        bool isQuickProperty; // need to call mappingObject->property to get value
        QVariant lastValue;
    } property_t;
    QList<property_t> m_properties;
};

#endif // PROPERTYMAPPER_H
